package com.aruba.socketlibrary.protocol.SocketManager;

import android.content.Context;

import com.aruba.socketlibrary.config.SerialportConfig;
import com.aruba.socketlibrary.protocol.handle.DataHandleDelegateImpl;
import com.aruba.socketlibrary.protocol.handle.IDataHandleDelegate;
import com.aruba.socketlibrary.utils.ByteBuf;
import com.aruba.socketlibrary.utils.Tools;
import com.socks.library.KLog;

import java.util.ArrayList;
import java.util.List;


/**
 * Created by aruba on 2017/10/19.
 * 返回数据的处理，校验数据并去除头部和校验位等，只派发实际数据
 */

public class HKSocketDataManager extends SocketDataManager {
    private static final String tag = HKSocketDataManager.class.getSimpleName();
    private ByteBuf cache = ByteBuf.allocate(2048);

    public HKSocketDataManager(Context context) {
        super(context);
    }

    @Override
    public void dataCallBack(byte[] readBuff, int size) {
        try {
            if (size <= 0) {
                KLog.i(tag, SerialportConfig.data_empty);
                return;
            }

            cache.put(readBuff, 0, size);
            processCache(cache);

        } catch (Exception e) {
            e.printStackTrace();
            cache = ByteBuf.allocate(2048);
            return;
        }
        return;
    }

    private void processCache(ByteBuf cache) {
        List<ByteBuf> packages = new ArrayList<>();
        // 可读的数据
        int readableBytes = cache.readableBytes();

        // 首先找到第一
        boolean findHead = false;
        ByteBuf pack = null;
        for (int i = 0; i < readableBytes; i++) {
            byte b = cache.get();
            // 已经找到包头
            if (findHead) {
                // 下一个55AA是包尾
                if (pack.getLast() == (byte) 0x55 && b == (byte) 0xAA) {
                    cache.discardRead();
                    readableBytes = cache.readableBytes();
                    findHead = false;
                    pack.put(b);
                    packages.add(pack);
                    continue;
                }

                pack.put(b);
            } else {
                byte b2 = cache.get();
                i++;
                //读到包开始标识 一个包数据开始了
                if (b == (byte) 0x55 && b2 == (byte) 0xAA) {
                    pack = ByteBuf.allocate(1024);
                    pack.put(b);
                    pack.put(b2);
                    findHead = true;
                } else {
                    // 丢弃已读
                    cache.discardRead();
                    readableBytes = cache.readableBytes();
                }
            }
        }
        cache.resetReadIndex();
        // packages: 所有完整的包数据
        for (ByteBuf p : packages) {
            int size = p.readableBytes();
            byte[] bytes = p.get(size);
            KLog.i(tag, "read：" + Tools.byteToHexString(bytes, size));
            try {
                disPatchData(bytes, size);
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private synchronized void disPatchData(byte[] readBuff, int size) {
//        //校验长度
//        int len = (readBuff[2] & 0xff) * 256 + (readBuff[3] & 0xff);
//        if (len != size - 7) {//减去头+长度+校验位+结束位 
//            KLog.i(tag, SerialportConfig.data_length_err);
//            return;
//        }
//
//        //校验校验码
//        int val = (readBuff[size - 3] & 0xff);
//        int myVal = Tools.makeCheckSum(readBuff);//从包长度到数据区数据的异或运算和
//        if (val != myVal) {
//            KLog.i(tag, SerialportConfig.data_val_err);
//            return;
//        }

        //报文控制字
        nCommand = readBuff[7];

        int defaultNuUse = SerialportConfig.no_use_length;//默认只有11位无用项(头+长度+命令字+校验位)
        int realIndex = 8;//真实数据索引
//            if (nCommand == (byte) 0xB8) {//11.	下发到外设的透明数据 0xaa 长度 0Xb8 flag Kind Data[0] Data[1] ...Data[N]校验和
//                //去除二次指令等无用项
//                defaultNuUse += 5;
//                realIndex += 5;
//                //二级指令
//                nSecondCommand = readBuff[5];
//            } else {
        nSecondCommand = 0;
//            }

        realData = new byte[size - defaultNuUse];
        System.arraycopy(readBuff, realIndex, realData, 0, realData.length);

        if (dataHandleDelegate != null) {
            dataHandleDelegate.dataAnalysis(nCommand, nSecondCommand, realData);
        }
    }

    @Override
    public IDataHandleDelegate getDataHandleDelegate() {
        return DataHandleDelegateImpl.getInstance();
    }
}
